package top.csmcool.musicapi.config;



import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.HttpClients;
import org.apache.hc.core5.util.Timeout;
import org.apache.hc.client5.http.config.RequestConfig;
import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;



@Configuration
public class HttpClientConfig {

    // 可以在 yml 或者 nacos 中配置此值，不配默认为200
    @Value("${restTemplate.pool.max:200}")
    private int poolMax;

    /**
     * HTTP 连接管理器: 针对单个 HTTP connection 的池化配置
     */
    @Bean
    public PoolingHttpClientConnectionManager poolingHttpClientConnectionManager() {
        PoolingHttpClientConnectionManager poolingHttpClientConnectionManager = new PoolingHttpClientConnectionManager();
        // 连接池里面的最大连接数
        poolingHttpClientConnectionManager.setMaxTotal(poolMax);
        // 单个路由的默认最大并发数(即允许同一个 host:port 最多有几个活跃连接)
        poolingHttpClientConnectionManager.setDefaultMaxPerRoute(poolMax);
        return poolingHttpClientConnectionManager;
    }

    /**
     * 单个 HTTP connection 的参数配置
     */
    @Bean
    public CloseableHttpClient httpClient(PoolingHttpClientConnectionManager poolingHttpClientConnectionManager) {
        RequestConfig requestConfig = RequestConfig.custom()
                .setConnectionRequestTimeout(Timeout.ofMinutes(1))
                .setResponseTimeout(Timeout.ofMinutes(1))
                .build();

        return HttpClients.custom()
                .setConnectionManager(poolingHttpClientConnectionManager)
                .setDefaultRequestConfig(requestConfig)
                .build();
    }

    @Bean
    public ClientHttpRequestFactory clientHttpRequestFactory(CloseableHttpClient httpClient) {
        HttpComponentsClientHttpRequestFactory clientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory(httpClient);
        // 连接超时时间/毫秒（连接上服务器(握手成功)的时间，超出抛出 connect timeout）
        clientHttpRequestFactory.setConnectTimeout(30000);
        // 连接池获取请求连接的超时时间，不宜过长，必须设置/毫秒（超时间未拿到可用连接，会抛出 org.apache.http.conn.ConnectionPoolTimeoutException: Timeout waiting for connection from pool）
        clientHttpRequestFactory.setConnectionRequestTimeout(1000);
        return clientHttpRequestFactory;
    }

    @Bean
    public RestTemplate restTemplate(ClientHttpRequestFactory clientHttpRequestFactory) {
        // boot中可使用 RestTemplateBuilder.build 创建
        return new RestTemplate(clientHttpRequestFactory);
    }
}